/**
 * Created by TamTT on 1/13/14.
 * FPT University - Da Nang
 * Capstone project - group 3
 * Jornee
 */

/**
 * Module dependencies.
 */
var express = require('express');
var http = require('http');
var path = require('path');
var cookie = require('cookie');
var fs = require('fs');
var jwt = require('jwt-simple');
var connect = require('connect');
var util = require('util');
var async = require("async");
var randomstring = require("randomstring");
var passwordHash = require('password-hash');
var Log = require('log'), log = new Log('info');
var colors = require('colors');
var config = require('config');
var secret = 'bRCEYwzMRX8aWixTwrajhsPtEALN8Z';
var app = express();

// Get deployment setting
app.is_deploy = config.is_deploy;

// Database setting
var dburl = config.dburl;
var collections = ['users', 'place', 'host', 'journey', 'tipsquestion', 'entry', 'comment', 'chat', 'notification', 'interestingplace', 'category', 'admin'];
var db = require('mongojs').connect(dburl, collections);

// Gmail configuration
var smtpTransport = config.smtpTransport;

// S3 client for uploading to Amazon S3
var s3Client = config.s3Client;

// All environments
app.set('port', process.env.PORT || 8888);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(express.favicon());

// Modified express logger
app.use(express.logger({
	stream: './log/',
	format: ':date :method :url - :status :res[content-length] :response-time ms'
}));
app.use(express.logger('dev'));

// parser
app.use(express.urlencoded())
app.use(express.json())
app.use(express.methodOverride());
app.use(express.cookieParser());
app.use(express.session({
	secret: 'pNAgwEQpBm2TErq2wfKeXFfAKQvDhs',
	key: 'express.sid',
	cookie: {
		secure: false
	}
}));
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));

// Development error handler
if('development' == app.get('env')){
	app.use(express.errorHandler());
}

// Logging error
process.on('uncaughtException', function(error){
	log.error('FATAL ERROR - Error with %s'.red, error.stack);
});

/**
 * Authentication function
 * Identify user
 */
function authentication(req, fn){
	var token = req.body.token;
	db.users.findOne({
		authentication: token
	}, function(err, result){
		if(err){
			log.error('Authen - Error with %s'.red, err);
			fn({
				loginStatus: 'error'
			});
		} else if(result == null){
			log.warning('Authen - Wrong token'.yellow);
			fn({
				loginStatus: 'false'
			});
		} else {
			log.info('Authen - User %s - Ok'.blue, result.username);
			fn({
				loginStatus: 'true',
				login_user: result.username
			});
		}
	});
};

/**
 * Change from vietnamese character to alphabet character
 */
var rule_a = ['á', 'à', 'ả', 'ã', 'ạ', 'ă', 'ắ', 'ằ', 'ẳ', 'ẵ', 'ặ', 'â', 'ấ', 'ầ', 'ẩ', 'ẫ', 'ậ'
];
var rule_u = ['ú', 'à', 'ủ', 'ũ', 'ụ', 'ư', 'ứ', 'ừ', 'ử', 'ữ', 'ự'
];
var rule_e = ['é', 'è', 'ẻ', 'ẽ', 'ẹ', 'ê', 'ế', 'ề', 'ể', 'ễ', 'ệ'
];
var rule_o = ['ó', 'ò', 'ỏ', 'õ', 'ọ', 'ô', 'ố', 'ồ', 'ổ', 'ỗ', 'ộ', 'ơ', 'ớ', 'ờ', 'ở', 'ỡ', 'ợ'
];
var rule_i = ['í', 'ì', 'ỉ', 'ĩ', 'ị'];
var rule_y = ['ý', 'ỳ', 'ỷ', 'ỹ', 'ỵ'];
var rule_d = ['đ'];

String.prototype.fromVi = function(){
	var i = 0;
	var result = '';
	while(this.hasOwnProperty(i + '')){
		if(rule_a.indexOf(this[i + ''].toLowerCase()) > -1){
			result += 'a';
		} else if(rule_u.indexOf(this[i + ''].toLowerCase()) > -1){
			result += 'u';
		} else if(rule_e.indexOf(this[i + ''].toLowerCase()) > -1){
			result += 'e';
		} else if(rule_o.indexOf(this[i + ''].toLowerCase()) > -1){
			result += 'o';
		} else if(rule_i.indexOf(this[i + ''].toLowerCase()) > -1){
			result += 'i';
		} else if(rule_y.indexOf(this[i + ''].toLowerCase()) > -1){
			result += 'y';
		} else if(rule_d.indexOf(this[i + ''].toLowerCase()) > -1){
			result += 'd';
		} else {
			result += this[i + ''].toLowerCase();
		}
		i++;
	}
	return result;
};

/**
 * Code structure for authentication
 */
app.post('/demo_authen', function(req, res){
	authentication(req, function(result){
		if(result.loginStatus == 'error'){
			res.send({
				authen_status: 'error'
			});
		} else if(result.loginStatus == 'false'){
			res.send({
				authen_status: 'fail'
			});
		} else if(result.loginStatus == 'true'){
			/**
			 * Code begin
			 */
				//Username: result.login_user
				//your code here
			res.send({
				authen_status: 'ok'
			});
		}
	});
});

/**
 * Homepage
 */
app.get('/', function(req, res){
	res.render('index.ejs', {
		title: 'Jornee'
	});
});

/**
 * Serve images
 */
app.get('/:image.jpg', function(req, res){
	var image = req.params.image;
	var image_info = image.split('_');
	var size = image_info[0];
	var name = image.slice(size.length + 1);
	if(app.is_deploy){
		s3Client.get('/images/' + size + '/' + name + '.jpg').on('response',function(res200){
			if(res200.statusCode == '404'){
				log.warning('Serve image - Image %s is NOT exist'.yellow, size + "_" +name);
				s3Client.get('/images/' + size + '/0.png').on('response',function(res404){
					if(res404.statusCode == '404'){
						res.end();
					}
					res404.pipe(res);
				}).end();
			} else {
				res200.pipe(res);
			}
		}).end();
	} else {
		fs.readFile('./users_data/images/' + size + '/' + name + '.jpg', function(err, photo){
			if(err){
				log.warning('Serve image - Image %s is NOT exist'.yellow, size + "_" +name);
				fs.readFile('./users_data/images/' + size + '/0.png', function(err, default_photo){
					if(err){
						fs.readFile('./users_data/images/small/0.png', function(err, missing_photo){
							if(err){
								log.warning('Serve image - Image %s is NOT exist'.yellow, name);
								res.writeHead(404);
								res.end();
							} else {
								res.end(missing_photo);
							}
						});
					} else {
						res.end(default_photo);
					}
				});
			} else {
				res.end(photo, 'binary');
			}
		});
	}
});

/**
 * Create server on port
 */
var server = http.createServer(app).listen(app.get('port'), function(){
	console.log('Express server listening on port ' + app.get('port'));
});

/**
 * Socket.io listen for server
 */
var io = require('socket.io').listen(server);
io.set('log level', 1); //Disable logging mode

/******** Start include routes ***********/
// account
route = require('./controllers/accountController.js');
route.controller(app, jwt, secret, db, authentication, util, connect, cookie, randomstring, smtpTransport, passwordHash, log, colors, s3Client);
// entry
route = require('./controllers/entryController.js');
route.controller(app, jwt, secret, db, authentication, util, async, log, colors, s3Client);
// journey
route = require('./controllers/journeyController.js');
route.controller(app, jwt, secret, db, authentication, util, async, io, log, colors);
// host
route = require('./controllers/hostController.js');
route.controller(app, jwt, util, secret, db, authentication, async, log, colors);
// location
route = require('./controllers/locationController.js');
route.controller(app, jwt, secret, db, authentication, util, async, log, colors);
// social
route = require('./controllers/socialController.js');
route.controller(app, jwt, secret, db, authentication, util, async, io, log, colors);
// admin
route = require('./controllers/adminController.js');
route.controller(app, jwt, secret, db, authentication, util, async, io, log, colors, s3Client);
/******** End include routes *************/